<template>
  <div class="overflow-hidden bg-white">
    <BasicTree
      :title="t('iot.route.device.title')"
      toolbar
      search
      tree-wrapper-class-name="h-[calc(100%-35px)] overflow-auto"
      :show-icon="false"
      :show-line="false"
      :click-row-to-expand="true"
      :default-expand-all="true"
      :tree-data="treeDataRef"
      v-if="treeDataRef.length"
      @select="handleSelect"
      ref="treeRef"
    />
  </div>
</template>
<script lang="ts" setup>
  import type { DeviceGroupTreeNode, DeviceNode } from '@/api/iot/admin/device/model';
  import type { TreeActionType, TreeItem } from '@/components/Tree';

  import { onBeforeUnmount, onMounted, ref, unref } from 'vue';

  import { isArray } from '@eacloud/utils';

  import { getDeviceGroupTreeNodeExclude, readDeviceNodes } from '@/api/iot/admin/device';
  import { BasicTree } from '@/components/Tree';
  import { useI18n } from '@/hooks/web/useI18n';
  import { useIdentityStoreWithOut } from '@/store/modules/identity';

  // import { getDeviceStatuses } from '@/api/iot';

  defineOptions({ name: 'DeviceTree' });

  const emit = defineEmits(['select']);

  const { t } = useI18n();

  const useIdentityStore = useIdentityStoreWithOut();
  const signalrHub = useIdentityStore.getSignalRHub;

  // const intervalTimer = ref<any>(null);

  const treeRef = ref<Nullable<TreeActionType>>(null);
  const treeDataRef = ref<TreeItem[]>([]);

  function getTree() {
    const tree = unref(treeRef);
    if (!tree) {
      // throw new Error('tree is null!');
      return null;
    }
    return tree;
  }

  async function fetch() {
    treeDataRef.value = [];

    // 获取设备组树
    const groupTreeNodes = await getDeviceGroupTreeNodeExclude();
    // 获取设备节点
    const deviceNodes = await readDeviceNodes();
    // 增加未分组栏
    const ungroupedNodes = deviceNodes.filter((o) => o.DvcGrpId === null);
    const deviceItems: TreeItem[] = ungroupedNodes.map((m) => {
      const deviceItem: TreeItem = {
        ...m,
        icon: m.Enabled ? (m.Connected ? 'mingcute:link-fill' : 'mingcute:unlink-fill') : 'mdi:pause-circle-outline',
        // @ts-ignore
        style: `color: ${m.Enabled ? (m.Connected ? 'green' : 'red') : 'blue'}`,
        key: m.Id as string,
        title: m.Name,
        group: false,
        // disabled: true,
        // isLeaf: !group.HasChildren,
      };
      return deviceItem;
    });
    treeDataRef.value = [
      ...treeDataRef.value,
      {
        // icon: 'carbon:tag-group',
        key: '0',
        title: t('iot.route.device.group.ungroupedText'),
        Id: '0',
        group: true,
        // disabled: true,
        children: deviceItems,
      },
    ];
    // 递归处理
    const groupedNodes = deviceNodes.filter((o) => o.DvcGrpId !== null);
    const treeItemData = makeTreeData(groupTreeNodes, groupedNodes);
    // const treeItemData = recursion(groupTreeNodes, groupedNodes);
    treeDataRef.value = [...treeDataRef.value, ...treeItemData];
  }

  // #region "处理设备树"
  function makeTreeData(groups: DeviceGroupTreeNode[], devices: DeviceNode[]): TreeItem[] {
    if (!groups.length) {
      return [];
    }
    const result: TreeItem[] = [];
    for (const group of groups) {
      const children: TreeItem[] = [];
      const item: TreeItem = {
        ...group,
        // icon: 'carbon:tag-group',
        key: group.Id as string,
        title: group.Name,
        group: true,
        // disabled: true,
        // isLeaf: !group.HasChildren,
      };
      const deviceItems: TreeItem[] = devices
        .filter((o) => o.DvcGrpId === group.Id)
        .map((m) => {
          const deviceItem: TreeItem = {
            ...m,
            icon: m.Enabled
              ? m.Connected
                ? 'mingcute:link-fill'
                : 'mingcute:unlink-fill'
              : 'mdi:pause-circle-outline',
            // @ts-ignore
            style: `color: ${m.Enabled ? (m.Connected ? 'green' : 'red') : 'blue'}`,
            key: m.Id as string,
            title: m.Name,
            group: false,
            // disabled: true,
            // isLeaf: !group.HasChildren,
          };
          return deviceItem;
        });
      if (deviceItems && deviceItems.length > 0) {
        deviceItems.forEach((d) => {
          children.push(d);
        });
      }
      if (group.Items && group.Items.length > 0) {
        const groupItems = makeTreeData(group.Items, devices);
        groupItems.forEach((g) => {
          children.push(g);
        });
      }
      item.children = children;
      result.push(item);
    }
    return result;
  }
  // #endregion
  // #region "监听设备"
  // function listenDevices() {
  //   // 每5秒检测设备状态
  //   intervalTimer.value = setInterval(async () => {
  //     const tree = getTree();
  //     if (tree != null) {
  //       try {
  //         const deviceStatuses = await getDeviceStatuses('none');
  //         if (deviceStatuses?.length > 0) {
  //           deviceStatuses.forEach((m) => {
  //             const key = m.DeviceId as string;
  //             tree.updateNodeByKey(key, {
  //               icon: m.Enabled
  //                 ? m.Connected
  //                   ? 'mingcute:link-fill'
  //                   : 'mingcute:unlink-fill'
  //                 : 'mdi:pause-circle-outline',
  //               // @ts-ignore
  //               style: `color: ${m.Enabled ? (m.Connected ? 'green' : 'red') : 'blue'}`,
  //               title: m.DeviceName,
  //             });
  //           });
  //         }
  //       } catch (ex) {
  //         // console.log(ex);
  //       }
  //     }
  //   }, 5000);
  // }
  // #endregion

  function handleSelect(selectedKeys: any, e: any) {
    // console.log('select', { selectedKeys, e, treeData: treeData.value });
    const selectedKey = selectedKeys[0];
    emit('select', selectedKey, e);
  }

  // 组件挂载完成后执行的函数
  onMounted(async () => {
    await fetch();
    // listenDevices();
    startListenMessage();
  });
  // 组件卸载前执行的函数
  onBeforeUnmount(() => {
    // console.log('onBeforeUnmount');
    // if (intervalTimer.value) {
    //   clearInterval(intervalTimer.value); // 清除定时器
    //   intervalTimer.value = null; // 定时器的变量赋值null
    // }
    stopListenMessage();
  });

  /** 启动监听消息 */
  function startListenMessage() {
    signalrHub?.on('IOT_DEVICE_STATE', (msg: any) => {
      const tree = getTree();
      if (tree !== null) {
        try {
          const deviceStatuses = isArray(msg) ? msg : [msg];
          if (deviceStatuses?.length > 0) {
            deviceStatuses.forEach((m: any) => {
              const key = m.DeviceId;
              tree.updateNodeByKey(key, {
                icon: m.Enabled
                  ? m.Connected
                    ? 'mingcute:link-fill'
                    : 'mingcute:unlink-fill'
                  : 'mdi:pause-circle-outline',
                // @ts-ignore
                style: `color: ${m.Enabled ? (m.Connected ? 'green' : 'red') : 'blue'}`,
                title: m.DeviceName,
              });
            });
          }
        } catch (ex) {
          console.error(ex);
        }
      }
    });
  }
  /** 停止监听消息 */
  function stopListenMessage() {
    signalrHub?.off('IOT_DEVICE_STATE');
  }
</script>
